/*******************************************
 * Copyright 2007 Aphrodite Framework for javaME .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * Email : owner@aphroditeme.dev.java.net
 * Contributors:
 *     Kent Elton - initial API and implementation
 *******************************************/

package com.aphrodite.ui.widgets;

import javax.microedition.lcdui.Graphics;

import com.aphrodite.util.geom.GeomUtil;

/**
 *<p>
 * Color Picker widget.
 * </P>
 * The Color range is predefined and can be set.
 * {@link ColorPicker#setColorArray(int[])}<br/> The following is the color
 * picker using the default color set.<br/> <img
 * src="../../../resources/picker.png"><br/> For a broader range of colors see
 * {@link RainbowPicker}
 * 
 * @author kentelt
 * 
 */
// must implement traverse
public class ColorPicker extends TraversableWidget {

	public static final int COLOR_SELECTED = 100000;
	protected int blockHeight = 10;
	// private int[] colorArray;
	protected int blockWidth = 10;
	protected int[] colorArray = new int[] { 0xFF8080, 0xFFFF80, 0x80FF80, 0x44EF97, 0x80FFFF, 0x0080FF, 0xFF80C0,
			0xFF80FF, 0xFF0000, 0xFFFF00, 0x80FF00, 0x00FF40, 0x00FFFF, 0x2A556B, 0x8080C0, 0xFF00FF, 0x804040,
			0xFF8040, 0x00FF00, 0x008080, 0x004080, 0x8080FF, 0x800040, 0xFF0080, 0x800000, 0xFF8000, 0x008000,
			0x008040, 0x0000FF, 0x0000A0, 0x800080, 0x8000FF, 0x400000, 0x804000, 0x004000, 0x004040, 0x000080,
			0x000040, 0x400040, 0x400080, 0x000000, 0x808000, 0x808040, 0x808080, 0x408080, 0xC0C0C0, 0x400040,
			0xFFFFFF };
	private int cols = 8;

	protected int currentCol = 0;

	protected int currentRow = 0;

	// protected ClickListener listener;

	private int rows = 6;

	/**
	 * Create a Color picker widget
	 */
	public ColorPicker(Theme theme) {
		this(theme, 6, 8);
	}

	/**
	 * Create a Color Picker Widget
	 * 
	 * @param theme
	 *            to be used by the widget
	 * @param rows
	 *            in the picker
	 * @param cols
	 *            in the picker
	 */
	public ColorPicker(Theme theme, int rows, int cols) {
		super(theme, 0, 0);
		this.rows = rows;
		this.cols = cols;
		updateModel();
	}

	ColorPicker(Theme theme, int w, int h, boolean dummy) {
		super(theme, w, h);
	}

	public void cleanUp() {
		colorArray = null;
		// widgetFont = null;
	}

	/**
	 * Get the color array currently in use.
	 */
	public int[] getColorArray() {
		return colorArray;
	}

	public int getSelectedColor() {
		return colorArray[currentRow * cols + currentCol];
	}

	public boolean moveDown() {
		if (currentRow < rows - 1) {
			currentRow++;
			reDrawWidget();
			return true;
		} else {
			isInFocus = false;
			return false;
		}
	}

	public boolean moveLeft() {
		if (currentCol > 0) {
			currentCol--;
			reDrawWidget();
			return true;
		}
		return false;
	}

	public boolean moveRight() {
		if (currentCol < cols - 1) {
			currentCol++;
			reDrawWidget();
			return true;
		}
		return false;
	}

	public boolean moveUp() {
		if (currentRow > 0) {
			currentRow--;
			reDrawWidget();
			return true;
		} else {
			isInFocus = false;
			return false;
		}
	}

	public boolean pointerDrag(int px, int py) {
		return pointerPress(px, py);
	}

	public boolean pointerPress(final int px, final int py) {
		if (isVisible && GeomUtil.withinBounds(px, py, x, y, width, height)) {
			// find the coordinate point within the widget
			final int contextX = px - x;
			final int contextY = py - y;
			int blockX = 0;
			int blockY = 0;
			for (int i = 0; i < rows; i++) {
				for (int j = 0; j < cols; j++) {
					if (GeomUtil.withinBounds(contextX, contextY, blockX, blockY, blockWidth, blockHeight)) {
						currentRow = i;
						currentCol = j;
						break;
					}
					blockX += blockWidth;
				}
				blockX = 0;
				blockY += blockHeight;
			}
			fire();
			return true;
		}
		return false;
	}

	public void render(Graphics g) {
		if (!isVisible)
			return;
		capture(g, width, height, false);
		g.setColor(theme.borderColor);
		g.drawRect(0, 0, width, height);
		int xtemp = 0;
		int ytemp = 0;

		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < cols; j++) {
				g.setColor(colorArray[i * cols + j]);
				g.fillRect(xtemp, ytemp, blockWidth, blockHeight);
				xtemp += blockWidth;
			}
			xtemp = 0;
			ytemp += blockHeight;
		}
		g.setColor(0);
		g.drawRect(currentCol * blockWidth, currentRow * blockHeight, blockWidth, blockHeight);
		g.setColor(0xffffff);
		g.drawRect((currentCol * blockWidth) + 1, (currentRow * blockHeight) + 1, blockWidth - 2, blockHeight - 2);
		release(g, width, height, true);

	}

	/**
	 * Change the color array used.
	 * 
	 * @param colors
	 *            represented in hex triplet
	 */
	public void setColorArray(int[] colors) {
		if (colors == null) {
			throw new NullPointerException();
		}
		this.colorArray = colors;
		reDrawWidget();
		stateChanged(this);
	}

	/**
	 * Set the height of each color block
	 * 
	 * @param height
	 *            in pixels. The default is 10.
	 */
	public void setColorBlockHeight(int height) {
		this.blockHeight = height;
		updateModel();
	}

	/**
	 * Set the width of each color block
	 * 
	 * @param width
	 *            in pixels. The default is 10.
	 */
	public void setColorBlockWidth(int width) {
		this.blockWidth = width;
		updateModel();
	}

	/**
	 * Set the number of rows and columns in the color picker.
	 * 
	 * @param rows
	 *            in the color picker. Default is 6
	 * @param columns
	 *            in the color picker. Default is 8
	 * @throws IllegalArgumentException
	 *             if <code>rows*cols</code> > number of colors used in the
	 *             picker
	 * @see ColorPicker#setColorArray(int[])
	 */
	public void setMatrix(int rows, int columns) {
		if (rows * columns > colorArray.length - 1) {
			throw new IllegalArgumentException();
		}
		this.rows = rows;
		this.cols = columns;
		updateModel();
		reDraw();
		stateChanged(this);
	}

	protected boolean traverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout) {
		return false;
	}

	protected void updateModel() {
		width = cols * blockWidth;
		height = rows * blockHeight;

	}

}
